import json

from django.contrib.auth.hashers import make_password
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView, LogoutView
from django.http import HttpResponseRedirect, HttpResponse, Http404, QueryDict
from django.shortcuts import render, get_object_or_404, resolve_url

from django.contrib.auth import (login as auth_login, update_session_auth_hash, REDIRECT_FIELD_NAME)
from django.conf import settings
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView, UpdateView, ListView, CreateView
from django.views.generic.base import View

from accounts.auth_session import auth_class
from accounts.forms import (UserRegisterForm, UserInitPasswordForm, ChangePasswordForm, ResetPasswordForm,
                            ResetPasswordDoneForm, DepartmentFrom)
from accounts.models import CustomUser, Department_Mode
from utils.tools import user_register_send_email, get_hash_token, user_reset_password_send_email, \
    user_passes_test_ext


class UserLoginView(LoginView):
    """ 用户登录 """
    template_name = "user/login.html"

    def form_valid(self, form):
        """登录,将权限设置到session中"""
        auth_login(self.request, form.get_user())
        request = self.request

        # 权限保存到session中
        auth_data = auth_class(self.request.user)
        request.session["fun_auth"] = auth_data  # todo 待测试
        user_data = get_object_or_404(CustomUser, email=request.user.email)
        user_data.session_key = request.session.session_key
        user_data.save()
        request.session.set_expiry(settings.USER_SESSION_EXPIRY)
        return HttpResponseRedirect(self.get_success_url())


class UserLogoutView(LogoutView):
    """ 用户退出登录 """
    template_name = ""


@method_decorator(user_passes_test_ext(permission_desc='add_user', redirect_to='no_permission'), name='dispatch')
class UserRegisterView(TemplateView):
    """
        用户注册 发送邮箱,由管理员填写用户信息,用户通过邮箱初始化密码
    """
    template_name = "user/reg.html"

    def get(self, request, *args, **kwargs):
        reg_form = UserRegisterForm()
        return render(request, self.template_name, context={"reg_form": reg_form})

    def post(self, request):
        reg_form = UserRegisterForm(request.POST)
        if reg_form.is_valid():
            reg_form.is_staff = 1
            new_user = reg_form.save(commit=False)
            new_user.save()

            # 发送注册信息到新建用户邮箱
            host = request.get_host()
            user_register_send_email(host=host, new_user=new_user, )
            return HttpResponseRedirect(reverse_lazy('user_list'))

        return render(request, self.template_name, context={"reg_form": reg_form})


class UserInitPasswordView(TemplateView):
    """ 用户注册 设置密码"""
    template_name = 'user/user_init_password.html'

    def get(self, request, *args, **kwargs):
        """ 通过pk查找用户, """
        pk = request.GET.get("pk", False)
        token = request.GET.get('token', False)

        data = get_object_or_404(CustomUser, pk=pk)

        # 检查token是否是伪造,必须一天时间内激活
        new_token = get_hash_token(data.username, data.pk)
        if token != new_token:
            raise Http404("页面没有找到")

        init_passwd_form = UserInitPasswordForm()
        context_data = {"form": init_passwd_form, "data": data, "pk": pk}
        return render(request, self.template_name, context_data)

    def post(self, request):

        pk = request.POST.get("pk")
        user_instance = get_object_or_404(CustomUser, pk=pk)
        user_obj_form = UserInitPasswordForm(request.POST, instance=user_instance)

        if user_obj_form.is_valid():
            user_obj_form.save(commit=True)
            return HttpResponseRedirect(reverse_lazy('user_login'))

        context_data = {"form": user_obj_form, "data": user_instance, "pk": pk}
        return render(request, self.template_name, context_data)


class UserChangePasswordView(TemplateView):
    template_name = 'user/change_password.html'

    def get(self, request, *args, **kwargs):
        form = ChangePasswordForm(request.user)
        return render(request, self.template_name, context={"form": form})

    def post(self, request):
        form = ChangePasswordForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(self.request, form.user)
            return HttpResponseRedirect(reverse_lazy('user_login'))
        return render(request, self.template_name, context={"form": form})


class UserResetPasswordView(TemplateView):
    """ 发送重置密码 """
    template_name = 'user/rest_password.html'

    def get(self, request, *args, **kwargs):
        form = ResetPasswordForm()
        return render(request, self.template_name, context={'form': form})

    def post(self, request):
        form = ResetPasswordForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get("email")
            user_obj = get_object_or_404(CustomUser, email=email)

            # pk 和token组成的url链接,发送到Email中
            host = request.get_host()
            user_reset_password_send_email(user_obj=user_obj, host=host)  # todo 异步
            is_send = True
            return render(request, self.template_name, context={"is_send": is_send})
        return render(request, self.template_name, context={'form': form})


class UserResetPasswordDoneView(TemplateView):
    """  确认重置密码 """
    template_name = 'user/user_reset_pwd_done.html'
    form = ResetPasswordDoneForm

    def get(self, request, *args, **kwargs):
        user_pk = request.GET.get("pk", False)
        token = request.GET.get('token', False)
        user_obj = get_object_or_404(CustomUser, pk=user_pk)

        # 检查token是否是伪造,必须一天时间内激活
        new_token = get_hash_token(user_obj.username, user_obj.pk)
        if token != new_token:
            raise Http404("页面没有找到")

        form = self.form()

        context = {'form': form, 'pk': user_pk}

        return render(request, self.template_name, context)

    def post(self, request):
        user_pk = QueryDict(request.body).get('pk', False)
        newpassword = QueryDict(request.body).get('newpassword', False)
        user_obj = get_object_or_404(CustomUser, pk=user_pk)

        form = self.form(request.POST, instance=user_obj)
        if form.is_valid():
            form.save(commit=False)
            form.password = make_password(newpassword)
            form.save()
            return HttpResponseRedirect(reverse_lazy('user_login'))
        context = {'form': form, 'pk': user_pk}
        return render(request, self.template_name, context)


@method_decorator(user_passes_test_ext(permission_desc='add_user', redirect_to='no_permission'), name='dispatch')
class UserListView(TemplateView):
    """ 用户列表"""
    template_name = 'user/user_list.html'

    def get(self, request, *args, **kwargs):
        user_list = CustomUser.objects.filter(is_active=True, )
        context = {'user_list': user_list}
        return render(request, self.template_name, context)


@method_decorator(user_passes_test_ext(permission_desc='add_user', redirect_to='no_permission'), name='dispatch')
class DisableUserListView(TemplateView):
    """ 禁用账号列表 """
    template_name = 'user/user_list.html'

    def get(self, request, *args, **kwargs):
        user_list = CustomUser.objects.filter(is_active=False, )
        context = {'user_list': user_list}
        return render(request, self.template_name, context)


@method_decorator(user_passes_test_ext(permission_desc='delete_user', redirect_to='no_permission'), name='dispatch')
class ChangeUserActiveStatusView(TemplateView):
    """ 修改用户禁用,启用状态 """
    template_name = "user/user_list.html"

    def get(self, request, *args, **kwargs):

        pk = kwargs.get('pk')
        user_obj = get_object_or_404(CustomUser, pk=pk)

        if user_obj.is_active:
            user_obj.is_active = False
        else:
            user_obj.is_active = True
        user_obj.save()

        return HttpResponseRedirect(reverse_lazy('user_list'))


#     TODO  用户列表,禁用列表, 离职列表 大量重复代码; 待优化

@method_decorator(user_passes_test_ext(permission_desc='edit_user', redirect_to='no_permission'), name='dispatch')
class ChangUserMenuStatusView(View):
    """ 修改用户菜单状态视图 """

    def get(self, request):
        user_name = request.user.username
        user_menu = CustomUser.objects.filter(username=user_name)

        if not user_menu.exists():
            content = {"status": 403, "message": "user object don't exists"}
            return HttpResponse(json.dumps(content, ensure_ascii=False, indent=4, ))

        user_menu = user_menu.first()
        if user_menu.menu_status:
            user_menu.menu_status = False
        else:
            user_menu.menu_status = True
        user_menu.save()
        content = {"status": 200, "message": "update is ok"}
        return HttpResponse(json.dumps(content, ensure_ascii=False, indent=4, ))


''' 
class DeleteUserView(TemplateView):
    """ 删除用户视图 伪删除 """
    template_name = 'user/user_list.html'

    # todo 'delete_user' 权限验证

    def get(self, request, *args, **kwargs):
        user_id = kwargs.get('pk')
        user_obj = get_object_or_404(CustomUser, pk=user_id)
        user_obj.is_active = False
        user_obj.is_staff = False
        user_obj.save()
        return HttpResponseRedirect(reverse_lazy('user_list'))
'''


@method_decorator(user_passes_test_ext(permission_desc='edit_user', redirect_to='no_permission'), name='dispatch')
class UserUpdataView(LoginRequiredMixin, UpdateView):
    """ 修改用户资料 """
    model = CustomUser
    fields = ("username", "email", "mobile", "user_key", "department")
    template_name = 'user/user_edit.html'
    success_url = reverse_lazy("user_list")
    context_object_name = "user_obj"


class UserInfoView(TemplateView):
    template_name = 'user/user_info.html'

    def get_context_data(self, **kwargs):
        user_obj = get_object_or_404(CustomUser, email=self.request.user.email)
        kwargs.update(user_obj=user_obj)
        return super().get_context_data(**kwargs)


@method_decorator(user_passes_test_ext(permission_desc='add_department', redirect_to='no_permission'), name='dispatch')
class CreateDepartmentView(CreateView):
    """ 创建部门 """
    form_class = DepartmentFrom
    template_name = 'user/create_department.html'
    success_url = reverse_lazy('department_list')

    def get_context_data(self, **kwargs):
        kwargs['department_from'] = self.get_form()
        return super().get_context_data(**kwargs)




@method_decorator(user_passes_test_ext(permission_desc='add_department', redirect_to='no_permission'), name='dispatch')
class DepartmentListView(ListView):
    """ 部门列表 """

    model = Department_Mode
    context_object_name = 'department_objs_list'
    template_name = 'user/department_list.html'


@method_decorator(user_passes_test_ext(permission_desc='add_department', redirect_to='no_permission'), name='dispatch')
class DepartmentUpdateView(UpdateView):
    """ 修改部门信息 """

    model = Department_Mode
    form_class = DepartmentFrom
    template_name = 'user/department_update.html'
    success_url = reverse_lazy('department_list')
